package com.kobeliu.controller;

import com.kobeliu.pojo.eo.SearchResumesEO;
import com.kobeliu.pojo.eo.Stu;
import com.kobeliu.result.GraceJSONResult;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.AggregationsContainer;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("es")
@Slf4j
public class HelloController {

    @Autowired
    private ElasticsearchRestTemplate esTemplate;


    @PostMapping("hello")
    public GraceJSONResult hello(){
        return GraceJSONResult.ok();
    }

    @PostMapping("createIndex")
    public GraceJSONResult createIndex(){
        esTemplate.indexOps(Stu.class).create();
        return GraceJSONResult.ok();
    }

    @PostMapping("deleteIndex")
    public GraceJSONResult deleteIndex(){
        esTemplate.indexOps(Stu.class).delete();
        return GraceJSONResult.ok();
    }

    @GetMapping("save")
    public GraceJSONResult save(){

        Stu stu = new Stu();
        stu.setStuId(1002L);
        stu.setAge(22);
        stu.setName("kobe");
        stu.setMoney(234.0F);
        stu.setDescription("never out");

        IndexQuery iq = new IndexQueryBuilder().withObject(stu).build();
        IndexCoordinates ic = IndexCoordinates.of("stu");

        esTemplate.index(iq,ic);

        return GraceJSONResult.ok();
    }

    @GetMapping("update")
    public GraceJSONResult update(){

        HashMap<String,Object> map = new HashMap<>();
        map.put("age",32);
        map.put("name","kobe");
        map.put("money",1000.0F);
        map.put("description","Disabled");

        UpdateQuery uq = UpdateQuery.builder("1001")
                .withDocument(Document.from(map))
                        .build();
        esTemplate.update(uq,IndexCoordinates.of("stu"));

        return GraceJSONResult.ok();
    }

    @GetMapping("search")
    public GraceJSONResult search(){

        //单条件查询
        //放入搜索条件
        Criteria criteria1 = new Criteria().and("stuId").is("1001");

        //多条件查询
        Criteria criteria2 = new Criteria("age").greaterThan(22)
                                        .and("money").greaterThan(33);

        //放入对象
        Query query1 = new CriteriaQuery(criteria1);
        Query query2 = new CriteriaQuery(criteria2);

        //进行搜索 根据ID查 唯一 所以是searchOne
        Stu stu = esTemplate.searchOne(query1, Stu.class).getContent();

        SearchHits<Stu> hits = esTemplate.search(query2, Stu.class);
        List<SearchHit<Stu>> searchHits = hits.getSearchHits();


        for (SearchHit<Stu> shs: searchHits){
            Stu s = shs.getContent();
            //拿到数据
        }


        return GraceJSONResult.ok(searchHits);
    }

    /**
     * 删除索引
     * @return
     */
    @GetMapping("delete")
    public GraceJSONResult delete(){

        //ById删除
        esTemplate.delete("1001",IndexCoordinates.of("stu"));

        //条件删除
        Criteria criteria = new Criteria("age").is(22);
        Query query = new CriteriaQuery(criteria);
        esTemplate.delete(query,com.kobeliu.pojo.Stu.class);

        return GraceJSONResult.ok();
    }

    /**
     * 查询所有
     * @return
     */
    @GetMapping("match_all")
    public GraceJSONResult matchAll(Integer page,Integer pageSize){

        if(page<1) page=1;

        //es的分页是从0开始，so此处page-1
        Pageable pageable = PageRequest.of(page-1,pageSize);

        //多条件查询构造器
        Query query = new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.matchAllQuery())
                        .withPageable(pageable)
                        .build();
        SearchHits<SearchResumesEO> search = esTemplate.search(query, SearchResumesEO .class);
        List<SearchResumesEO> eos = search.stream().map(obj -> {
            SearchResumesEO eo = obj.getContent();
            return eo;
        }).collect(Collectors.toList());

        return GraceJSONResult.ok(eos);
    }

    /**
     *  term  where XXX=XX
     * @return
     */
    @GetMapping("term")
    public GraceJSONResult term(){


        //es的分页是从0开始，so此处page-1
        Pageable pageable = PageRequest.of(0,5);

        //多条件查询构造器
        Query query = new NativeSearchQueryBuilder()
                //条件查询
                .withQuery(QueryBuilders.termQuery("sex",1))
                .withQuery(QueryBuilders.termQuery("beginSalary",5000))
                .withPageable(pageable)
                .build();
        SearchHits<SearchResumesEO> search = esTemplate.search(query, SearchResumesEO .class);
        List<SearchResumesEO> eos = search.stream().map(obj -> {
            SearchResumesEO eo = obj.getContent();
            return eo;
        }).collect(Collectors.toList());

        return GraceJSONResult.ok(eos);
    }

    /**
     * match  模糊查询   es对对查询的字段进行分词
     * @return
     */
    @GetMapping("match")
    public GraceJSONResult match(){


        //es的分页是从0开始，so此处page-1
        Pageable pageable = PageRequest.of(0,5);

        //多条件查询构造器
        Query query = new NativeSearchQueryBuilder()
                //条件查询
                .withQuery(QueryBuilders.matchQuery("major","电子工程"))
                .withPageable(pageable)
                .build();
        SearchHits<SearchResumesEO> search = esTemplate.search(query, SearchResumesEO .class);
        List<SearchResumesEO> eos = search.stream().map(obj -> {
            SearchResumesEO eo = obj.getContent();
            return eo;
        }).collect(Collectors.toList());

        return GraceJSONResult.ok(eos);
    }

}
